package com.gitee.chili.leisure.util;

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.*;

/**
 * TaskManager
 *
 * @author week solider
 * @since 2020.09.14
 */
public class TaskManager {


    /**
     * 定时任务集
     * 充当容器的角色, 存储了所有的全局定时任务, 任务的键都是固定的
     */
    private static final Map<String, Timer> tasks = new HashMap<>(258);

    /**
     * 房间内特定玩家的定时任务集
     * 充当容器的角色, 存储了所有的特定定时任务, 任务的键使用房间号
     */
    private static final MultiValueMap<String, MemberTimer> specificTaskMap = new LinkedMultiValueMap<>(256);


    /**
     * 添加一个全局定时任务
     */
    public static void set(String name, Timer timer) {
        tasks.put(name, timer);
    }

    /**
     * 获取一个定时任务
     *
     * @param name 定时任务的键
     */
    public static Timer get(String name) {
        return tasks.get(name);
    }

    /**
     * 清除全局定时任务
     */
    public static void clear(String name) {
        get(name).cancel();
        tasks.remove(name);
    }

    /**
     * 缓存中是否已经存这个定时器
     *
     * @param name 定时器的名称
     * @return if exist is true , else false
     */
    public static boolean contains(String name) {
        return tasks.containsKey(name);
    }

    /**
     * 添加一个特定的定时任务
     *
     * @param name        任务标识房间号
     * @param memberTimer 任务归属
     */
    public static void add(String name, MemberTimer memberTimer) {
        specificTaskMap.add(name, memberTimer);
    }

    /**
     * 获取一个特定的定时任务
     *
     * @param name     任务标识房间号
     * @param memberId 玩家id
     */
    public static Timer get(String name, Long memberId) {
        List<MemberTimer> memberTimers = specificTaskMap.get(name);
        if (Objects.isNull(memberId) || memberTimers.isEmpty()) {
            return null;
        }

        Optional<MemberTimer> optional = memberTimers.stream()
                .filter(mt -> mt.getMemberId().equals(memberId)).findFirst();

        return optional.map(MemberTimer::getTimer).orElse(null);
    }

    /**
     * 移除特定的任务
     *
     * @param name     任务标识房间号
     * @param memberId 玩家id
     * @return 如果有元素被删除返回 {@code true}
     */
    public static void remove(String name, Long memberId) {
        specificTaskMap.get(name).removeIf(channel -> {
            boolean flag = channel.getMemberId().equals(memberId);
            if (flag) {
                channel.getTimer().cancel();
            }
            return flag;
        });
    }


    /**
     * 所有全局任务的名称
     */
    public interface TaskNames {

        /**
         * 投票解散房间 (依据房间来进行标识)
         */
        String voteDissolvedName = "voteDissolvedRoom-%s";

        /**
         * 出牌 (依据玩家ID来进行标识)
         */
        String discardName = "discard-%s";

        /**
         * 房间内玩家操作类型任务 (依据玩家ID进行标识)
         */
        String memberOperateName = "memberOperate-%s";

        /**
         * 房间标识符
         */
        String room = "room-%s";

        /**
         * 换三张 (多人任务)
         */
        String multiExchangeThree = "multiExchangeThree-%s";

        /**
         * 定缺 (多人)
         */
        String multiUseless = "multiUseless-%s";

    }
}
